package com.itaming.lycheeframework.mybatisplus.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.itaming.lycheeframework.mybatisplus.autofill.AutoFillProvider;
import com.itaming.lycheeframework.mybatisplus.autofill.DefaultMetaObjectHandler;
import com.itaming.lycheeframework.mybatisplus.properties.LycheeMybatisPlusProperties;
import com.itaming.lycheeframework.support.properties.ExtendedPropertySource;
import com.itaming.lycheeframework.support.utils.CollectionUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

import java.util.List;

/**
 * MybatisPlus模块配置类
 *
 * @author A.Ming
 */
@AutoConfiguration
@EnableConfigurationProperties({LycheeMybatisPlusProperties.class})
@ExtendedPropertySource({"classpath:lychee-mybatis-plus.yml"})
@RequiredArgsConstructor
public class LycheeMybatisPlusConfiguration {

    /**
     * MybatisPlus配置参数
     */
    private final LycheeMybatisPlusProperties properties;

    /**
     * 自动填充提供者
     */
    @Bean
    @ConditionalOnMissingBean
    public AutoFillProvider autoFillUserProvider() {
        return new AutoFillProvider.Impl();
    }

    /**
     * 数据填充处理器
     */
    @Bean
    @ConditionalOnMissingBean
    public MetaObjectHandler metaObjectHandler(AutoFillProvider autoFillProvider) {
        return new DefaultMetaObjectHandler(autoFillProvider);
    }

    /**
     * MybatisPlus拦截器
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(List<InnerInterceptor> interceptors) {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();

        PaginationInnerInterceptor paginationInterceptor = null;

        // 添加自定义的拦截器
        // 在项目中定义InnerInterceptor实现类即可
        if (CollectionUtil.isNotEmpty(interceptors)) {
            for (InnerInterceptor interceptor : interceptors) {
                // 分页拦截器最后处理
                if (interceptor instanceof PaginationInnerInterceptor) {
                    paginationInterceptor = (PaginationInnerInterceptor) interceptor;
                    continue;
                }

                mybatisPlusInterceptor.addInnerInterceptor(interceptor);
            }
        }

        // 默认分页拦截器
        if (paginationInterceptor == null) {
            paginationInterceptor = new PaginationInnerInterceptor();
            paginationInterceptor.setOverflow(properties.getPagination().isOverflow());
            paginationInterceptor.setMaxLimit(properties.getPagination().getMaxLimit());
            paginationInterceptor.setDbType(properties.getPagination().getDbType());
            paginationInterceptor.setOptimizeJoin(properties.getPagination().isOptimizeJoin());
        }

        // 官方建议：如果配置多个插件, 切记分页最后添加，以避免 COUNT SQL 执行不准确的问题
        mybatisPlusInterceptor.addInnerInterceptor(paginationInterceptor);

        return mybatisPlusInterceptor;
    }

}
